package com.lagou.rpc.proxy;

import com.alibaba.fastjson.JSONObject;
import com.lagou.common.RpcRequest;
import com.lagou.common.RpcResponse;
import com.lagou.rpc.balance.RpcLoadBanlance;
import com.lagou.rpc.netty.RpcClinetChannelHolder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.UUID;

/**
 * @ClassName RpcProxy
 * @Description
 * @Author playboy
 * @Date 2021/6/5 4:06 下午
 * @Version 1.0
 **/
@Component
public class RpcProxy {

	@Autowired
	private RpcLoadBanlance rpcLoadBanlance;


	public <T> T getProxy(Class<T> clazz) {
		return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
				new Class[]{clazz},
				new InvocationHandler() {
					@Override
					public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
						RpcRequest rpcRequest = new RpcRequest();
						rpcRequest.setRequestId(UUID.randomUUID().toString());
						rpcRequest.setClassName(clazz.getName());
						rpcRequest.setMethodName(method.getName());
						rpcRequest.setParameterTypes(method.getParameterTypes());
						rpcRequest.setParameters(objects);
						RpcClinetChannelHolder channel = rpcLoadBanlance.getChannel();
						try {
							long start = System.currentTimeMillis();
							String send = channel.send(JSONObject.toJSONString(rpcRequest));
							long end = System.currentTimeMillis();
							System.out.println("服务端响应时间为：" + (end - start) + "毫秒");
							rpcLoadBanlance.setResponseTime(channel, (end - start));
							RpcResponse rpcResponse = JSONObject.parseObject(send, RpcResponse.class);
							if (rpcResponse.getError() != null) {
								throw new RuntimeException(rpcResponse.getError());
							} else {
								return JSONObject.parseObject(JSONObject.toJSONString(rpcResponse.getResult()), method.getReturnType());
							}
						} catch (Exception e) {
							throw e;
						}
					}
				});
	}

}
